<html>
  <head>
    <style>
        #main{
        display: flex;
        }

        #graph {
        width: 800px;
        height: 800px;
        }

        #control {
        width: 500px;
        height: 800px;
        }

        #list {
        width: 480px;
        height: 300px;
        margin: 10px;
        }

        #details {
        width 480px;
        height: 440px;
        margin: 10px;
        }

        #title {
        text-align: center;
        font-size: 12px;
        }

        #leaderboard_table {
        width: 95%;
        margin: 10px;
        }

        #details_table {
        width: 95%;
        margin: 10px;
        }

        .bordered {
        border: 2px solid grey;
        }

        #leaderboard_div {
        height: 240px;
        }

        #details_div {
        height: 380px;
        }

        .scrollit {
        overflow-x: hidden;
        overflow-y: auto;
        }

        tr:nth-child(even) {
        background-color: #D6EEEE;
        }

        table, th, td {
        border: 1px solid black;
        }
    </style>
  </head>
  <body>
    <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js'></script>

    <div id='main' class='bordered'>
      <div id='graph' class='bordered'></div>
      <div id='control' class='bordered'>
        <div id='list' class='bordered'>
          <div id='title'>
            <h2>Leaderboard</h2>
          </div>
          <div id='leaderboard_div' class='scrollit'>
            <table id='leaderboard_table'></table>
          </div>
        </div>
        <div id='details' class='bordered'>
          <div id='title'>
            <h2>Details</h2>
          </div>
          <div id='details_div' class='scrollit'>
            <table id='details_table'></table>
          </div>
        </div>
      </div>
    </div>

    <script>
        var graphData = {{graph_data}};
        var typeMap = new Map([
        ['r', 'repo'], ['i', 'issue'], ['p', 'pull'], ['u', 'user']
        ]);

        var container = document.getElementById('graph');
        var chart = echarts.init(container);

        var clearDiv = id => {
            var div = document.getElementById(id);
            if (div && div.hasChildNodes()) {
                var children = div.childNodes;
                for (var child of children) {
                div.removeChild(child);
                }
            }
        }

        var addRow = (table, texts) => {
            var tr = table.insertRow();
            for (var t of texts) {
                var td = tr.insertCell();
                td.appendChild(document.createTextNode(t));
            }
        }

        var genName = node => (node.c == 'i' || node.c == 'p') ?
                `#${node.n.toString()}` : node.n.toString();

        var setLeaderboard = graph => {
            clearDiv('leaderboard_table');
            var table = document.getElementById('leaderboard_table');
            addRow(table, ['Login', 'OpenRank']);
            var users = graph.nodes.filter(c => c.c === 'u').sort((a, b) => b.v - a.v);
            for (var u of users) {
                addRow(table, [u.n, u.v]);
            }
        }

        var setDetails = (graph, node) => {
            clearDiv('details_table');
            var table = document.getElementById('details_table');
            addRow(table, ['From', 'Ratio', 'Value', 'OpenRank']);
            addRow(table, [ 'Self', node.r, node.i, (node.r * node.i).toFixed(3) ]);
            var other = graph.edges.filter(l => l.t == node.id).map(l => {
                var source = graph.nodes.find(n => n.id == l.s);
                return [
                genName(source),
                parseFloat((1 - node.r) * l.w).toFixed(3),
                source.v, 
                parseFloat(((1 - node.r) * l.w * source.v).toFixed(3))
                ];
            }).sort((a, b) => b[3] - a[3]);
            for (var r of other) {
                addRow(table, r);
            }
        }

        var onGraphDataLoaded = graph => {
            setLeaderboard(graph);
            var nodes = graph.nodes.map(node => {
                return {
                id: node.id,
                name: genName(node),
                symbolSize:  Math.log(node.v + 1) * 6,
                value: node.v,
                category: typeMap.get(node.c),
                };
            });
            var links = graph.edges.map(link => {
                return {
                source: link.s,
                target: link.t,
                value: link.w,
                };
            });
            var categories = Array.from(typeMap.values());
            var option = {
                title: {
                text: `OpenRank details`,
                top: 'bottom',
                left: 'right'
                },
                legend: [
                {
                    data: categories,
                }
                ],
                tooltip: {
                trigger: 'item',
                },
                series: [
                {
                    name: 'Collaborative graph',
                    type: 'graph',
                    layout: 'force',
                    nodes,
                    links,
                    categories: categories.map(c => { return { name: c }; }),
                    roam: true,
                    label: {
                    position: 'right',
                    show: true,
                    },
                    force: {
                    layoutAnimation: false,
                    repulsion: 300
                    },
                }
                ]
            };
            chart.setOption(option);
            chart.on('dblclick', function(params) {
                setDetails(graph, graph.nodes.find(i => i.id === params.data.id));
            });
        }

        onGraphDataLoaded(graphData);
    </script>
  </body>
</html>
